package com.youlu.campus.activity.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.youlu.campus.activity.entity.UserLotteryRecord;
import com.youlu.campus.activity.entity.UserLotteryRecordExcel;
import com.youlu.campus.activity.entity.UserLotteryRecordQueryVo;
import com.youlu.campus.activity.repositories.UserLotteryRecordRepository;
import com.youlu.campus.activity.service.ActivityInfoService;
import com.youlu.campus.activity.service.UserLotteryRecordService;
import com.youlu.campus.base.exception.BusinessException;
import com.youlu.campus.entity.ActivityInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.support.PageableExecutionUtils;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 抽奖记录服务实现类
 */
@Slf4j
@Service
public class UserLotteryRecordServiceImpl implements UserLotteryRecordService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private UserLotteryRecordRepository userLotteryRecordRepository;

    @Autowired
    private ActivityInfoService activityInfoService;

    @Override
    public Page<UserLotteryRecord> findByPage(UserLotteryRecordQueryVo paramVo) {
        Query query = new Query();
        if (StringUtils.isNotBlank(paramVo.getActivityName())) {
            query.addCriteria(Criteria.where("activityName").regex(paramVo.getActivityName()));
        }
        if (StringUtils.isNotBlank(paramVo.getUserNickeName())) {
            query.addCriteria(Criteria.where("userNickeName").regex(paramVo.getUserNickeName()));
        }
        if (StringUtils.isNotBlank(paramVo.getActivityId())) {
            query.addCriteria(Criteria.where("activityId").is(paramVo.getActivityId()));
        }
        if (StringUtils.isNotBlank(paramVo.getMobile())) {
            query.addCriteria(Criteria.where("mobile").is(paramVo.getMobile()));
        }
        if (Objects.nonNull(paramVo.getStatus())) {
            query.addCriteria(Criteria.where("status").is(paramVo.getStatus()));
        }
        if (Objects.nonNull(paramVo.getRecordType())) {
            query.addCriteria(Criteria.where("recordType").is(paramVo.getRecordType()));
        }
        //统计总条数（分页需要先查总数）
        long total = mongoTemplate.count(query, UserLotteryRecord.class);
        //创建分页对象
        Pageable pageRequest = PageRequest.of(paramVo.getPage() - 1, paramVo.getPageSize(), Sort.by("drawTime").descending());
        List<UserLotteryRecord> list;
        if (total == 0) {
            list = Arrays.asList();
        } else {
            // 应用分页（设置跳过的条数和查询的条数）
            query.skip(pageRequest.getOffset()).limit(pageRequest.getPageSize());
            // 应用排序
            query.with(pageRequest.getSort());
            list = mongoTemplate.find(query, UserLotteryRecord.class);
        }
        return PageableExecutionUtils.getPage(list, pageRequest, () -> total);
    }

    @Override
    public UserLotteryRecord addRecord(UserLotteryRecord record) {
        // 设置抽奖时间
        record.setDrawTime(LocalDateTime.now());
        // 默认为未领取状态
        if (record.getStatus() == null) {
            record.setStatus(0);
        }
        log.info("addRecord record:{}", record);
        return userLotteryRecordRepository.insert(record);
    }

    @Override
    public void save(UserLotteryRecord record) {
        ActivityInfo activityInfo = activityInfoService.findById(record.getActivityId());
        if (Objects.isNull(activityInfo)) {
            log.info("save activity is null");
            throw new BusinessException("活动不存在!");
        }
        if (record.getDrawTime() == null) {
            record.setDrawTime(LocalDateTime.now());
        }
        record.setActivityName(activityInfo.getName());
        log.info("save record:{}", record);
        userLotteryRecordRepository.save(record);
    }

    @Override
    public void updateRecordStatus(String recordId, Integer status) {
        log.info("updateRecordStatus recordId:{},status:{}", recordId, status);
        Optional<UserLotteryRecord> optional = userLotteryRecordRepository.findById(recordId);
        if (!optional.isPresent()) {
            throw new BusinessException("记录不存在!");
        }
        UserLotteryRecord record = optional.get();
        record.setStatus(status);
        // 如果是已领取状态，设置领取时间
        if (status == 1) {
            record.setReceiveTime(LocalDateTime.now());
        }
        log.info("updateRecordStatus record:{}", record);
        userLotteryRecordRepository.save(record);

    }

    @Override
    public Page<UserLotteryRecord> findListByActivityIdAndUserId(String userId, UserLotteryRecordQueryVo paramVo) {

        Query query = new Query();
        query.addCriteria(Criteria.where("activityId").regex(paramVo.getActivityId()));
        query.addCriteria(Criteria.where("userId").is(userId));
        //统计总条数（分页需要先查总数）
        long total = mongoTemplate.count(query, UserLotteryRecord.class);
        //创建分页对象
        Pageable pageRequest = PageRequest.of(paramVo.getPage() - 1, paramVo.getPageSize(), Sort.by("drawTime").descending());
        List<UserLotteryRecord> list;
        if (total == 0) {
            list = Arrays.asList();
        } else {
            // 应用分页（设置跳过的条数和查询的条数）
            query.skip(pageRequest.getOffset()).limit(pageRequest.getPageSize());
            // 应用排序
            query.with(pageRequest.getSort());
            list = mongoTemplate.find(query, UserLotteryRecord.class);
        }
        return PageableExecutionUtils.getPage(list, pageRequest, () -> total);
    }

    @Override
    public List<UserLotteryRecord> findNew(String activityId) {
        List<UserLotteryRecord> all = userLotteryRecordRepository.findByRecordTypeAndActivityId(UserLotteryRecord.RECORD_TYPE_SYSTEM, activityId);
        return all;
    }

    @Override
    public void importSystem(List<UserLotteryRecordExcel> excelDataList) {
        log.info("importSystem excelDataList:{}", JSONObject.toJSONString(excelDataList));
        LocalDateTime now = LocalDateTime.now();
        //查询活动信息
        Map<String, List<UserLotteryRecordExcel>> map = excelDataList.stream().collect(Collectors.groupingBy(UserLotteryRecordExcel::getActivityId));
        for (Map.Entry<String, List<UserLotteryRecordExcel>> entry : map.entrySet()) {
            String activityId = entry.getKey();
            List<UserLotteryRecordExcel> list = entry.getValue();

            //删除老数据
            userLotteryRecordRepository.deleteByActivityIdAndRecordType(activityId, UserLotteryRecord.RECORD_TYPE_SYSTEM);

            ActivityInfo activityInfo = activityInfoService.findById(activityId);
            if (Objects.isNull(activityInfo)) {
                log.info("importSystem activity is null");
                continue;
            }
            //对象转换
            List<UserLotteryRecord> records = new ArrayList<>(list.size());
            for (UserLotteryRecordExcel excelRecord : list) {
                UserLotteryRecord userLotteryRecord = new UserLotteryRecord();
                userLotteryRecord.setUserNickeName(excelRecord.getUserNickeName());
                userLotteryRecord.setActivityId(excelRecord.getActivityId());
                userLotteryRecord.setActivityName(activityInfo.getName());
                userLotteryRecord.setPrizeName(excelRecord.getPrizeName());
                userLotteryRecord.setPrizeType(2);
                userLotteryRecord.setOneCount(0);
                userLotteryRecord.setDrawTime(now);
                userLotteryRecord.setStatus(1);
                userLotteryRecord.setRemark(excelRecord.getRemark());
                userLotteryRecord.setRecordType(UserLotteryRecord.RECORD_TYPE_SYSTEM);
                records.add(userLotteryRecord);

            }
            //批量插入
            List<UserLotteryRecord> userLotteryRecords = userLotteryRecordRepository.saveAll(records);
        }
    }

    @Override
    public UserLotteryRecord findById(String recordId) {
        return userLotteryRecordRepository.findById(recordId).orElse(null);
    }

    @Override
    public void deleteById(String id) {
        userLotteryRecordRepository.deleteById(id);
    }
}
    